package com.edmendst.xmall.filter;

import com.edmendst.xmall.util.JWTUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;


//JWT过滤器整合到spring security 中
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    RedisTemplate redisTemplate;

    private final JWTUtil jwtUtil;


    public JwtAuthenticationFilter(JWTUtil jwtUtil) {
        if (jwtUtil == null) {
            throw new IllegalArgumentException("jwtUtil不能为null");
        }
        this.jwtUtil = jwtUtil;
        System.out.println("JWTUtil实例的secret值: " + jwtUtil.getSecret()); // 添加验证日志
    }

    /**
     * 过滤器内部处理逻辑，用于提取并验证JWT令牌
     *
     * @param request  HTTP请求对象，包含客户端请求信息
     * @param response HTTP响应对象，用于构建返回内容
     * @param chain    过滤器链对象，用于传递请求和响应
     * @throws ServletException 当请求处理过程中发生Servlet异常
     * @throws IOException      当发生输入输出异常
     */


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {


        String path = request.getServletPath();
        String method = request.getMethod();

        // 放行回调接口
        if ("/pay/callback".equals(path)) {
            chain.doFilter(request, response);
            return;
        }


        // 放行精确匹配
        if ("GET".equalsIgnoreCase(method)) {
            if (path.equals("/product")
                    || path.matches("/product/\\d+")
                    || path.equals("/product/category")
                    || path.matches("/product/category/\\d+")) {
                chain.doFilter(request, response);
                return;
            }
        }

        if (path.startsWith("/product/keyword/")) {
            chain.doFilter(request, response);
            return;
        }

        // 新增：放行图片路径
        if (path.startsWith("/product_images/")
                || path.startsWith("/user_images/")
                || path.startsWith("/shop_images/")
                || path.equals("/icon.png")) {
            chain.doFilter(request, response);
            return;
        }


        // 放行登录、注册接口（用户和管理员）
        if ("/user/session".equals(path) ||
                (method.equals("POST") && "/user".equals(path)) ||
                "/admin/session".equals(path) ||
                (method.equals("POST") && "/admin".equals(path))) {
            chain.doFilter(request, response);
            return;
        }

        // 提取Authorization头
        String header = request.getHeader("Authorization");

        // 验证Token是否存在且格式正确
        if (header == null || !header.startsWith("Bearer ")) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "缺少有效的Token");
            return;
        }

        // 提取并验证Token
        String token = header.substring(7);


        // 验证 Token 基本有效性
        if (!jwtUtil.validateToken(token)) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token无效或已过期");
            return;
        }

// 解析 Token 获取用户名
        Claims claims = jwtUtil.parseToken(token); // 获取claims
        String username = claims.get("username", String.class);

        //token是否在黑名单中
        String key = "jwt:blacklist:" + token;
        if (redisTemplate.hasKey(key)) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token已加入黑名单");
            return;
        }
//        if (redisTemplate.hasKey(key)) {
//            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token已加入黑名单");
//            return;
//        }

        try {
            if (jwtUtil.validateToken(token)) {

                String role = claims.get("role", String.class); // 获取角色
                AuthorityUtils.createAuthorityList(role);
                // 在JwtAuthenticationFilter中解析后设置认证信息
                UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
                        username, null, AuthorityUtils.createAuthorityList("ROLE_"+role));
                SecurityContextHolder.getContext().setAuthentication(auth);
            } else {
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token无效或已过期");
                return;
            }
        } catch (Exception e) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token验证失败");
            return;
        }

        // 继续执行后续过滤器
        chain.doFilter(request, response);
    }
}
